<template>
  <div class="main-content-box">
    <div class="demoDiv">
      <div class="title_for_layout">
        <h3>3.5版本新增comboforce 布局</h3>
      </div>
      <div class="toolDiv">
        <div class="zoom zoomOut" title="放大" @click="getZoomOut">
          <i class="iconfont">&#xe640;</i>
        </div>
        <div class="zoom zoomIn" title="缩小" @click="getZoomIn">
          <i class="iconfont">&#xe624;</i>
        </div>
        <div class="zoom refreshViews" title="刷新拓扑图" @click="refreshViews">
          <i class="iconfont">&#xe64d;</i>
        </div>
      </div>
      <div id="container"></div>
    </div>
  </div>
</template>

<script>
import G6 from '@antv/g6';
import Util from "@antv/g6/lib/util";
import { getComboForce } from "../../../nodeApi/api/getData.js"
export default {
  name: 'g6ComboForce',
  data () {
    return {
      orgData: {},
      currentGraph: {},
      colors: [
        '#BDD2FD',
        '#BDEFDB',
        '#C2C8D5',
        '#FBE5A2',
        '#F6C3B7',
        '#B6E3F5',
        '#D3C6EA',
        '#FFD8B8',
        '#AAD8D8',
        '#FFD6E7',
      ],
      strokes: [
        '#5B8FF9',
        '#5AD8A6',
        '#5D7092',
        '#F6BD16',
        '#E8684A',
        '#6DC8EC',
        '#9270CA',
        '#FF9D4D',
        '#269A99',
        '#FF99C3',
      ]
    }
  },
  mounted () {
    getComboForce().then(res => {
      // console.log(res)
      if (res.status === 1) {
        this.orgData = res.data
        /**
         * 此处对数据进行部分字段的处理，避免使用graph.node()方法报错
         * 渲染时控制台报错， The source or target node of edge undefined does not exist!
         * 原因为数据中 id使用number类型，edges中使用为string类型
         */
        this.orgData.nodes.forEach((item, index) => {
          item.label = '' + item.id
          if (!item.style) item.style = {};
          item.style.fill = this.colors[index % this.colors.length]
          item.style.stroke = this.strokes[index % this.strokes.length]
        })
        this.orgData.edges.forEach((item, index) => {
          if (!item.style) item.style = {};
          item.style.fill = this.colors[index % this.colors.length]
          item.style.stroke = this.strokes[index % this.strokes.length]
          /* if (index > 1) {
            item.label = 'source:node ' + item.source + ' to ' + 'node ' + item.target
          } */
        })
        setTimeout(() => {
          this.initGraph()
        }, 10);
      }
    })
  },
  methods: {
    initGraph () {
      let _that = this
      // console.log(_that)

      const width = document.getElementById('container').scrollWidth;
      const height = document.getElementById('container').scrollHeight || 650;
      const minimap = new G6.Minimap({
        size: [100, 80]
      })
      const grid = new G6.Grid();
      const graph = new G6.Graph({
        container: 'container',
        width,
        height,
        fitView: true,
        fitViewPadding: 50,
        /**
         * comboForce 布局，为3.5版本新增
         */
        layout: {
          type: 'comboForce',
          nodeSpacing: d => 8
        },
        defaultNode: {
          size: 25,
          color: '#5B8FF9',
          style: {
            lineWidth: 2,
            fill: '#C6E5FF',
          },
        },
        defaultEdge: {
          size: 2,
          color: '#e2e2e2',
        },
        modes: {
          default: [
            'drag-combo',
            'drag-node',
            'drag-canvas',
            'zoom-canvas',
            'activate-relations',
            'collapse-expand-combo', //收起和展开 Combo,默认触发方式为双击，可配置click或dblclick

          ]
        },
        plugins: [grid, minimap],
        nodeStateStyles: {
          active: {
            opacity: 1,
          },
          inactive: {
            opacity: 0.2,
          },
        },
        edgeStateStyles: {
          active: {
            lineWidth: 5,
            stroke: 'cyan',
            // lineDash: [4, 2, 2, 4]  //设置此属性显示时 效果不够直观
          },
        },
        defaultCombo: {
          type: 'circle',
          // 其他配置
          labelCfg: {
            position: 'top',
            offset: [10, 10, 10, 10],
            style: {
              fill: 'red',
            },
          }
        },
      });

      graph.data(_that.orgData);
      graph.render();
      // graph.fitView()
      _that.currentGraph = graph
    },
    /**
     * 拓扑图的缩小、放大
     */
    getZoomOut () {
      let currentZoom = this.currentGraph.getZoom();
      this.currentGraph.zoomTo(currentZoom + 0.1, this.getViewCenter());
    },
    getZoomIn () {
      const currentZoom = this.currentGraph.getZoom();
      this.currentGraph.zoomTo(currentZoom - 0.1, this.getViewCenter());
    },
    getFormatPadding () {
      return Util.formatPadding(this.currentGraph.get("fitViewPadding"));
    },
    getViewCenter () {
      const padding = this.getFormatPadding();
      // console.log(padding)
      const graph = this.currentGraph;
      const width = this.currentGraph.get("width");
      const height = graph.get("height");
      return {
        x: (width - padding[2] - padding[3]) / 2 + padding[3],
        y: (height - padding[0] - padding[2]) / 2 + padding[0],
      };
    },
    /**
     * 刷新拓扑图
     */
    refreshViews () {
      this.currentGraph.destroy();
      setTimeout(() => {
        this.initGraph()
      }, 0);
    },
    /**
     * 还原拓扑图，即重新渲染视图
     */
    reFreshNodeOrg () {

    }
  },
  destroyed () {
    console.log('销毁了comboforce')
    this.currentGraph.clear()
    this.currentGraph.destroy();
  }
}
</script>

<style scoped>
.main-content-box {
  width: 95%;
  margin: 5px 10px;
}
.demoDiv {
  position: relative;
  padding: 20px;
  /* border: 1px solid skyblue; */
  /* min-height: 600px; */
}
.toolDiv {
  width: 50px;
  border: 1px solid #f5f5f5;
  position: absolute;
  z-index: 100;
}
.title_for_layout {
  position: absolute;
  top: 0;
  left: 100px;
  color: crimson;
}
.zoom {
  cursor: pointer;
  border: 1px solid #f5f5f5;
  font-size: 26px;
  background-color: #ffffff;
}
</style>